package algebra.rewriting.kfree;

import java.util.HashSet;
import java.util.Set;

import option.KBVocabulary;

import kb.DescriptionLogicsKB;

import reasoner.KBReason;
import utils.exception.CoreReasoningException;

import algebra.op.*;

import entities.concept.AndConcept;
import entities.concept.Concept;
import entities.concept.DomainConceptEQ;
import entities.role.Role;

public class LangRep {

	public static Set<Concept> getOPRepConcepts(AlgebraicOP op, Set<String> ks,
			DescriptionLogicsKB kb) {
		// System.err.println("Get Lpd from: "+op+" using constants: "+ks );
		Set<Concept> ret = new HashSet<Concept>();
		if (op instanceof ConstantOP) {
			ConstantOP cp = (ConstantOP) op;
			ret.add(cp.getQueryCocnept());
		} else if (op instanceof PrimaryOP) {
			ret.add(KBVocabulary.CONCEPT_TOP);
		} else if (op instanceof ScanOP) {
			ScanOP scan = (ScanOP) op;
			ret = LangPd.getLangPd(scan.getSecondaryIndex().getPdi(), ks, kb);
		} else if (op instanceof SelectionOP) {
			SelectionOP sel = (SelectionOP) op;
			ret = getOPRepConcepts(sel.getSubquery(), ks, kb);
		} else if (op instanceof ProjectionOP) {
			ProjectionOP pj = (ProjectionOP) op;
			ret = LangPd.getLangPd(pj.getPrjDesc(), ks, kb);
		} else if (op instanceof JoinOP) {
			JoinOP ip = (JoinOP) op;
			for (Concept c : getOPRepConcepts(ip.getFirstSubQuery(), ks, kb)) {
				for (Concept d : getOPRepConcepts(ip.getSecondSubQuery(), ks,
						kb)) {
					ret.add(new AndConcept(c, d));
				}
			}
		} else {
			System.err.println("Unknown algebraic OP type: " + op);
		}
		return ret;
	}

	//complexity too high...
	public static boolean EqConceptSet(Set<Concept> lq1, Set<Concept> lq2,
			boolean subOnly, DescriptionLogicsKB kb) {
		// System.err.println("size to check: "+lq1.size()+" / "+lq2.size());
		for (Concept c : lq1) {
			if (lq2.contains(c)) {
				continue;
			}
			if (subOnly && (c instanceof DomainConceptEQ)) {
				DomainConceptEQ<?, ?> dc = (DomainConceptEQ<?, ?>) c;
				Concept fstar = new DomainConceptEQ<Role, String>(
						(Role) dc.getRealFeature(), KBVocabulary.AnyStringInKB);
				if (lq2.contains(fstar)) {
					continue;
				}
			}
			boolean found = false;
			for (Concept d : lq2) {
				KBReason res = new KBReason();
				try {
					if (res.subsumesGuarded(d, c, kb)) {
						if (subOnly || res.subsumesGuarded(c, d, kb)) {
							found = true;
							break;
						}
					}
				} catch (CoreReasoningException e) {
					e.printStackTrace();
				}
			}
			if (found) {
				continue;
			} else {
				return false;
			}
		}
		return true;
	}

}
